package ru.ifmo.tanya.keepers;

import ru.ifmo.tanya.core.huntgroups.HuntGroup;
import ru.ifmo.tanya.core.users.User;
import ru.ifmo.tanya.core.users.UserState;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * User: nikart
 * Date: 1/27/13
 * Time: 2:51 AM
 */
public class UserStatusKeeper {

    private static final ConcurrentMap<User, Set<HuntGroup>> user2Groups = new ConcurrentHashMap<>();

    private final UserStateKeeper userStateKeeper = new UserStateKeeper();

    public void addGroupToUser(User user, HuntGroup group) {
        Set<HuntGroup> groupSet = user2Groups.get(user);
        if (groupSet == null) {
            groupSet = new HashSet<>();
            user2Groups.put(user, groupSet);
        }
        groupSet.add(group);
    }

    public void removeGroupFromUser(User user, HuntGroup group) {
        Set<HuntGroup> groups = user2Groups.get(user);
        if (groups != null) {
            groups.remove(group);
        }
    }

    public Set<HuntGroup> getGroupsByUser(User user) {
        Set<HuntGroup> huntGroups = user2Groups.get(user);
        if (huntGroups != null) {
            return huntGroups;
        } else {
            return new HashSet<>();
        }
    }

    public Map<HuntGroup, Integer> getAgentsByGroup() {

        Map<HuntGroup, Integer> result = new HashMap<>();
        for (final Map.Entry<User, Set<HuntGroup>> entry : user2Groups.entrySet()) {
            for (final HuntGroup group : entry.getValue()) {
                Integer value = result.get(group);
                if (value == null) {
                    result.put(group, 1);
                } else {
                    result.put(group, value + 1);
                }
            }
        }

        return result;
    }

    public Map<HuntGroup, Integer> getActiveAgentsByGroup() {

        Map<HuntGroup, Integer> result = new HashMap<>();
        for (final Map.Entry<User, Set<HuntGroup>> entry : user2Groups.entrySet()) {
            if (userStateKeeper.getUserState(entry.getKey()) != UserState.AVAILABLE) {
                continue;
            }
            for (final HuntGroup group : entry.getValue()) {
                Integer value = result.get(group);
                if (value == null) {
                    result.put(group, 1);
                } else {
                    result.put(group, value + 1);
                }
            }
        }

        return result;
    }

    public List<User> getActiveUsersByGroup(HuntGroup group) {
        List<User> result = new ArrayList<>();
        for (final Map.Entry<User, Set<HuntGroup>> entry : user2Groups.entrySet()) {
            if (entry.getValue().contains(group) && userStateKeeper.getUserState(entry.getKey()) == UserState.AVAILABLE) {
                result.add(entry.getKey());
            }
        }
        return result;
    }
}
